#include "../include/TLVmsg.h"
#include <iostream>
#include <istream>
#include <string.h>
using std::istream;
using std::endl;
using std::cout;
TLVmsg::TLVmsg(string &tlvmsg)
    :_data(tlvmsg)
    ,_typeTagLen(2)
     ,_msgTagLen(4)
     ,_isrecursive(false)
{
    
}

void TLVmsg::parse_tlv()
{
     size_t offset = 0;

    while (offset + 6 <= _data.size()) {  // 至少需要 2(Tag) + 4(Length) 字节
        // 解析Tag
        uint16_t tag = (static_cast<uint8_t>(_data[offset]) << 8) |
                       static_cast<uint8_t>(_data[offset + 1]);
        _tasktype = tag;
        offset += 2;

        // 解析Length
        uint32_t length = (static_cast<uint8_t>(_data[offset]) << 24) |
                          (static_cast<uint8_t>(_data[offset + 1]) << 16) |
                          (static_cast<uint8_t>(_data[offset + 2]) << 8) |
                          static_cast<uint8_t>(_data[offset + 3]);
        _valuelen = length;
        offset += 4;

        // 验证剩余数据长度
        if (offset + length > _data.size()) {
            throw std::runtime_error("数据不完整，无法解析Value");
        }

        // 提取Value
        std::string value = _data.substr(offset, length);
        _value = value;
        offset += length;
        
        
    }
}
string TLVmsg::build_tlv(int tag, int len,const string &value)
{
      // 验证长度一致性
    if (static_cast<size_t>(len) != value.length()) {
        throw std::invalid_argument("Length 参数与 Value 长度不匹配");
    }

    // 转换为协议所需的固定字节宽度（假设 tag 为 2 字节，len 为 4 字节）
    uint16_t tag16 = static_cast<uint16_t>(tag);
    uint32_t len32 = static_cast<uint32_t>(len);

    // 结果字符串（预分配足够空间）
    std::string result;
    result.reserve(6 + len);  // Tag(2) + Length(4) + Value(len)

    // 添加 Tag（2字节，大端序）
    result.push_back(static_cast<char>((tag16 >> 8) & 0xFF));
    result.push_back(static_cast<char>(tag16 & 0xFF));

    // 添加 Length（4字节，大端序）
    result.push_back(static_cast<char>((len32 >> 24) & 0xFF));
    result.push_back(static_cast<char>((len32 >> 16) & 0xFF));
    result.push_back(static_cast<char>((len32 >> 8) & 0xFF));
    result.push_back(static_cast<char>(len32 & 0xFF));

    // 添加 Value
    result.append(value);

    return result;
}
